package utils

import (
	"fmt"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

// AbsPath 绝对路径，可获取当前文件所在角色路径，skips设置可获取调用量上一级的
func AbsPath(skips ...int) string {
	skip := 0
	if len(skips) > 0 {
		skip = skips[0]
	}
	// 获取当前文件的路径
	_, filename, _, ok := runtime.Caller(skip)
	if !ok {
		panic(fmt.Errorf("not fetch abs path"))
	}

	return path.Dir(filename)
}

// BasePath 运行的程序所在目录
func BasePath() string {
	exe, err := os.Executable()
	if err != nil {
		panic("Cannot get executable folder, just panic: " + err.Error())
	}
	basePath := filepath.Dir(exe)
	return basePath
}

// CurrentPath 当前目录(与运行程序所在目录无关)
func CurrentPath() string {
	basePath, err := filepath.Abs("./")
	if err != nil {
		panic(err)
	}
	return basePath
}

// FileExt 获取文件后缀
func FileExt(file string) string {
	arr := strings.Split(file, ".")
	return arr[len(arr)-1]
}

// IsExistPath 文件或目录是否存在
func IsExistPath(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsExist(err) {
			return true
		}
		if os.IsNotExist(err) {
			return false
		}
		return false
	}
	return true
}

// EnsureDir 确保目录存在
func EnsureDir(dirPath string) error {
	if IsExistPath(dirPath) {
		return nil
	}
	err := os.MkdirAll(dirPath, os.ModePerm)
	if err == nil || os.IsExist(err) {
		return nil
	} else {
		return err
	}
}

// FilePathExist 文件路径是否存在
var FilePathExist = IsExistPath

// ScanDirFileDo 扫描目录文件并执行操作
func ScanDirFileDo(dir string, fn func(file string, path string) error) error {
	files, err := os.ReadDir(dir)
	if err != nil {
		return err
	}
	for _, f := range files {
		path := dir + "/" + f.Name()
		//文件路径
		if strings.HasSuffix(dir, "/") {
			path = dir + f.Name()
		}
		if dir == "." {
			path = f.Name()
		}

		//目录则继续扫描
		if f.IsDir() {
			if err := ScanDirFileDo(path, fn); err != nil {
				return err
			}
			continue
		}
		//文件则func处理
		if err := fn(f.Name(), path); err != nil {
			return err
		}
	}
	return nil
}
